import * as fs from 'fs';

import { CharStreams, CommonTokenStream } from 'antlr4ts';
import { ParseTree } from 'antlr4ts/tree/ParseTree';
import { TerminalNode } from 'antlr4ts/tree/TerminalNode';
import { AbstractParseTreeVisitor } from 'antlr4ts/tree/AbstractParseTreeVisitor'

import { TextDocuments, Range, Position } from 'vscode-languageserver/node';
import {
    TextDocument
} from 'vscode-languageserver-textdocument';
import { URI } from 'vscode-uri';


import { ArkcubeScriptLexer } from '../gen/ArkcubeScriptLexer';
import { ArkcubeScriptVisitor } from '../gen/ArkcubeScriptVisitor';
import * as ArkcubeScriptParser from '../gen/ArkcubeScriptParser';

import { SymbolTable, Symbol, SymbolLocation } from './SymbolTable';




class SymbolCollector extends AbstractParseTreeVisitor<void> implements ArkcubeScriptVisitor<void> {
    constructor(
        private uri: string,
        private symbolTable: SymbolTable
    ) {
        super();
    }

    protected defaultResult(): void {
        return;
    }

    visitFunctionDecl(ctx: ArkcubeScriptParser.FunctionDeclContext): void {
        const nameNode: TerminalNode = ctx.Identifier();
        if (!nameNode) return;

        const name = nameNode.text;
        const range = this.createRange(nameNode.symbol);

        const symbol = new Symbol(name, 'function', range);
        const location: SymbolLocation = { uri: this.uri, range };
        this.symbolTable.addSymbol(this.uri, symbol, location);

        // 处理参数
        const parameterList = ctx.parameterList();
        if (parameterList) {
            this.visit(parameterList);
        }

        // 处理函数体
        const block = ctx.block();
        if (block) {
            this.visit(block);
        }
    }

    visitVariableDecl(ctx: ArkcubeScriptParser.VariableDeclContext): void {
        const nameNode = ctx.Identifier();
        if (!nameNode) return;

        const name = nameNode.text;
        const range = this.createRange(nameNode.symbol);

        const symbol = new Symbol(name, 'variable', range);
        const location: SymbolLocation = { uri: this.uri, range };
        this.symbolTable.addSymbol(this.uri, symbol, location);
    }

    private createRange(token: any): Range {
        const start = Position.create(token.line - 1, token.charPositionInLine);
        const end = Position.create(
            token.line - 1,
            token.charPositionInLine + token.text.length
        );
        return Range.create(start, end);
    }

    // 实现其他必要visit方法...
    visit(tree: ParseTree): void {
        if (tree instanceof ArkcubeScriptParser.FunctionDeclContext) {
            this.visitFunctionDecl(tree);
        } else if (tree instanceof ArkcubeScriptParser.VariableDeclContext) {
            this.visitVariableDecl(tree);
        }
        // 递归访问子节点
        for (let i = 0; i < tree.childCount; i++) {
            const child = tree.getChild(i);
            if (child) {
                this.visit(child);
            }
        }
    }
}

// 符号表
const symbolTable = new SymbolTable();

export function parse(uri: string, tree: ParseTree, clear: boolean): void {
    if (clear) symbolTable.clear(uri);
    if (!symbolTable.has(uri)) {
        const visitor = new SymbolCollector(uri, symbolTable);
        visitor.visit(tree);
    }
}


